package com.qkl.xiatang.app.workflow.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qkl.xiatang.app.dto.BusinessDTO;
import com.qkl.xiatang.app.dto.upload.UploadFileWebDTO;
import com.qkl.xiatang.app.entity.pond.PondEntity;
import com.qkl.xiatang.app.entity.upload.UploadFileEntity;
import com.qkl.xiatang.app.entity.user.AppUserInfo;
import com.qkl.xiatang.app.mapper.AppUserInfoMapper;
import com.qkl.xiatang.app.mapper.PondManagerMapper;
import com.qkl.xiatang.app.service.impl.ConfigService;
import com.qkl.xiatang.app.utils.*;
import com.qkl.xiatang.app.workflow.dto.TaskFunctionRelDto;
import com.qkl.xiatang.app.workflow.dto.WorkFlowDto;
import com.qkl.xiatang.app.workflow.service.IWorkFlowService;
import com.qkl.xiatang.app.workflow.utils.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class WorkFlowServiceImpl implements IWorkFlowService {

    private static final String DOWNLOAD_URL = "/downloadApi/";

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private PondManagerMapper pondManagerMapper;

    @Autowired
    private AppUserInfoMapper appUserInfoMapper;

    @Autowired
    private ConfigService configService;


    @Override
    public Result workflowPageOnWay(int pageIndex, int pageSize) {
        WorkFlowDto<Map<String, Object>> pageVo = buildWorkFlowDto(pageIndex, pageSize);
        return doHandleResult(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPageOnWay", pageVo));
    }

    @Override
    public Result workflowPageOnWayDone(int pageIndex, int pageSize) {
        WorkFlowDto<Map<String, Object>> pageVo = buildWorkFlowDto(pageIndex, pageSize);
        Map<String, Object> requestVo = new HashMap<>();
        requestVo.put("status", "done");
        requestVo.put("identity", "user");
        pageVo.setRequestVo(requestVo);
        return doHandleResultAndSelectPondName(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPageOnWay", pageVo));
    }

    @Override
    public Result workflowPageOnDone(int pageIndex, int pageSize) {
        WorkFlowDto<Map<String, Object>> pageVo = buildWorkFlowDto(pageIndex, pageSize);
        Map<String, Object> requestVo = new HashMap<>();
        requestVo.put("status", "done");
        requestVo.put("identity", "admin");
        pageVo.setRequestVo(requestVo);
        return doHandleResultAndSelectPondName(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPageOnWay", pageVo));
    }

    @Override
    public Result workflowPageOnWayPending(int pageIndex, int pageSize) {
        WorkFlowDto<Map<String, Object>> pageVo = buildWorkFlowDto(pageIndex, pageSize);
        Map<String, Object> requestVo = new HashMap<>();
        requestVo.put("status", "pending");
        requestVo.put("identity", "user");
        pageVo.setRequestVo(requestVo);
        return doHandleResultAndSelectPondName(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPageOnWay", pageVo));
    }

    @Override
    public Result workflowPageOnPending(int pageIndex, int pageSize) {
        WorkFlowDto<Map<String, Object>> pageVo = buildWorkFlowDto(pageIndex, pageSize);
        Map<String, Object> requestVo = new HashMap<>();
        requestVo.put("status", "pending");
        requestVo.put("identity", "admin");
        pageVo.setRequestVo(requestVo);
        return doHandleResultAndSelectPondName(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPageOnPending", pageVo));
    }

    @Override
    public Result workflowPageOnWayReject(int pageIndex, int pageSize) {
        WorkFlowDto<Map<String, Object>> pageVo = buildWorkFlowDto(pageIndex, pageSize);
        Map<String, Object> requestVo = new HashMap<>();
        requestVo.put("status", "reject");
        requestVo.put("identity", "admin");
        pageVo.setRequestVo(requestVo);
        return doHandleResultAndSelectPondName(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPageOnReject", pageVo));
    }

    private WorkFlowDto<Map<String, Object>> buildWorkFlowDto(int pageIndex, int pageSize) {
        if (pageIndex == 0) {
            pageIndex = 1;
        }
        if (pageSize == 0) {
            pageSize = 10;
        }
        WorkFlowDto<Map<String, Object>> pageVo = new WorkFlowDto<>();
        pageVo.setCurrentPage(pageIndex);
        pageVo.setPageSize(pageSize);
        return pageVo;
    }


    @Override
    public Result selectTaskDetail(Integer id) {
        WorkFlowDto<Object> workFlowDto = new WorkFlowDto<>();
        workFlowDto.setId(id);
        workFlowDto.setSign(CommonCryptoUtils.encryptEncodedUpload(AppSessionUtils.getUserName()));
        return doHandleResult(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/selectTaskDetail", workFlowDto));
    }

    @Override
    public Result workflowPageOnWayCount() {
        Map<String, Object> requestVo = new HashMap<>();
        requestVo.put("identity", "user");
        return doHandleResult(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPageOnWayCount", requestVo));
    }

    @Override
    public Result workflowPageOnAdminCount() {
        Map<String, Object> requestVo = new HashMap<>();
        requestVo.put("identity", "admin");
        return doHandleResult(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPageOnWayCount", requestVo));
    }

    @Override
    public Result selectCurrentTask(String businessId, String businessKey) {
        PondEntity pondEntity = pondManagerMapper.selectOnePondAndCompanyName(businessId);
        String companyName = pondEntity.getCompanyName();
        String name = pondEntity.getName();
        Map<String, Object> requestVo = new HashMap<>();
        requestVo.put("businessId", businessId);
        requestVo.put("businessKey", businessKey);
        requestVo.put("companyName", companyName);
        requestVo.put("pondName", name);
        return doHandleResult(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/selectCurrentTask", requestVo));
    }

    @Override
    public Result complete(Map<String, Object> requestBody) {
        AppUserInfo sessionUser = AppSessionUtils.getSessionUser();
        if (sessionUser == null) {
           return Result.error("请先登录!");
        }
        requestBody.put("approval", sessionUser.getUsername());
        requestBody.put("approvalName", sessionUser.getName());
        return doHandleResult(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/complete", requestBody));
    }

    @Override
    public Result reject(Map<String, Object> requestBody) {
        AppUserInfo sessionUser = AppSessionUtils.getSessionUser();
        if (sessionUser == null) {
            return Result.error("请先登录!");
        }
        requestBody.put("approval", sessionUser.getUsername());
        requestBody.put("approvalName", sessionUser.getName());
        return doHandleResult(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/reject", requestBody));
    }

    @Override
    public BusinessDTO<Object> completeUploadFile(UploadFileWebDTO webDTO) {

        String ownerUserId = StringUtils.trimToEmpty(webDTO.getOwnerUserId());
        String fileSuffix = StringUtils.trimToEmpty(webDTO.getFileSuffix());
        String fileTime = StringUtils.trimToEmpty(webDTO.getFileTime());
        String taskId = StringUtils.trimToEmpty(webDTO.getTaskId());
        if(StringUtils.isAnyEmpty(ownerUserId, taskId)){
            return BusinessDTO.failBusiness(ErrorCodeUtils.PARAM_EMPTY, ErrorCodeUtils.PARAM_EMPTY_MSG);
        }

        AppUserInfo ownerUser = appUserInfoMapper.selectById(ownerUserId);
        if(null == ownerUser){
            return BusinessDTO.failBusiness("无拍摄者用户信息");
        }

        String fileDirPath = FileUtils.uploadDirPath(ownerUser.getCompanyId());
        String fileName = FileUtils.genFilePrefix() + "." + FileUtils.getFileSuffix(fileSuffix);
        String filePath = fileDirPath + fileName;

        String uploadId = AppUtils.genIdStr();
        String downloadUrl = configService.uploadFileUrl() + DOWNLOAD_URL + filePath;

        UploadFileEntity uploadFile = new UploadFileEntity();
        uploadFile.setFileTime(parseFileTime(fileTime));
        uploadFile.setUploadUserId(AppSessionUtils.getUserId());
        uploadFile.setUploadUserName(AppSessionUtils.getUserName());
        uploadFile.setTaskId(taskId);
        uploadFile.setOwnerUserId(ownerUserId);
        uploadFile.setOwnerUserName(ownerUser.getName());
        uploadFile.setUploadFlag(1);
        uploadFile.setDownloadUrl(downloadUrl);
        uploadFile.setFilePath(filePath);

        JSONObject requestBody = JSONObject.parseObject(JSONObject.toJSONString(uploadFile));
        requestBody.put("uploadId", uploadId);

        HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/file/uploadFile", requestBody);


        return BusinessDTO.sucessBusiness(uploadResponse(fileDirPath,filePath,uploadId),"文件上传成功!");
    }

    @Override
    public Result workflowPage(TaskFunctionRelDto taskFunctionRelDto) {

        int pageIndex = taskFunctionRelDto.getPageIndex();
        int pageSize = taskFunctionRelDto.getPageSize();

        if (pageIndex == 0) {
            pageIndex = 1;
        }
        if (pageSize == 0) {
            pageSize = 10;
        }

        WorkFlowDto<TaskFunctionRelDto> pageVo = new WorkFlowDto<>();
        pageVo.setCurrentPage(pageIndex);
        pageVo.setPageSize(pageSize);
        pageVo.setRequestVo(taskFunctionRelDto);

        return doHandleResultAndSelectPondName(HttpUtil.post(restTemplate, "http://workflow-system/workflow/api/task/status/workflowPage", pageVo));
    }

    /**
     * 处理结果
     * @param result
     * @return
     */
    private Result doHandleResult(String result) {
        JSONObject resultObject = JSONObject.parseObject(result);
        String state = resultObject.getString("state");
        if ("200".equalsIgnoreCase(state)) {
            Object data = resultObject.get("data");
            return Result.success(data);
        }
        else {
            return Result.error(resultObject.getString("message"));
        }
    }

    /**
     * 处理结果
     * @param result
     * @return
     */
    private Result doHandleResultAndSelectPondName(String result) {
        JSONObject resultObject = JSONObject.parseObject(result);
        String state = resultObject.getString("state");
        if ("200".equalsIgnoreCase(state)) {
            JSONObject data = resultObject.getJSONObject("data");
            JSONArray rows = data.getJSONArray("rows");
            for (int i = 0; i < rows.size(); i++) {

                JSONObject object = rows.getJSONObject(i);

                String businessId = object.getString("businessId");

                PondEntity pondEntity = pondManagerMapper.selectById(businessId);
                if (pondEntity != null) {
                    object.put("pondName", pondEntity.getName());
                }

                String downloadUrl = object.getString("downloadUrl");
                if (StringUtils.isNotBlank(downloadUrl)) {
                    object.put("downloadUrl", downloadUrl + "?sign=" + CommonCryptoUtils.encryptEncodedUpload(AppSessionUtils.getUserName()));
                }

            }
            return Result.success(data);
        }
        else {
            return Result.error(resultObject.getString("message"));
        }
    }


    private Date parseFileTime(String fileTime){
        if(StringUtils.isNotEmpty(fileTime)){
            try {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fileTime);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return null;
    }

    private Map<String,Object> uploadResponse(String fileDirPath,String filePath,String uploadId){
        Map<String,Object> map = new HashMap<>();
        map.put("fileDirPath", fileDirPath);
        map.put("filePath", filePath);
        map.put("uploadId", uploadId);
        return map;
    }

}
